﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Script.Services;
using System.Web.Services;
using EasyLibrary.AR;
using EasyLibrary.AR.Classes;
using EasyLibrary.AR.Services;

namespace EasyFrota_Mobile.Servicos
{
    /// <summary>
    /// Summary description for ServicoRotas
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    [System.Web.Script.Services.ScriptService]
    public class ServicoRotas : System.Web.Services.WebService
    {
        [WebMethod]
        public string HelloWorld()
        {
            return "Hello World";
        }

        [WebMethod]
        [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
        public List<Hashtable> GetRotaMarcas(int idRota)
        {
            List<Hashtable> d = new List<Hashtable>();

            //BDconn dbAccess = new BDconn();
            RotaMarca rm = new RotaMarca();
            var rotas = rm.getMarcasByRota(idRota);
            //  var linha = ar.executeCommandOnDataSet(" SELECT Viaturas.IDViaturas, Viaturas.matricula, TiposViatura.TipoViatura, Viaturas.Longitude,                                                                        Viaturas.Latitude FROM  Viaturas INNER JOIN TiposViatura ON Viaturas.RefIDTiposViatura =                                                                        TiposViatura.IDTiposViatura WHERE (Viaturas.IDViaturas = " + IdViatura + ")");
            string l;
            for (int i = 0; i < rotas.Count; i++)
            {
                d.Add(new Hashtable
                          {
                              {"IDRota", rotas[i].Rota.IDRota.ToString()},
                              {"Morada", rotas[i].Morada.ToString()},
                              {"Label", rotas[i].Label.ToString()},
                              {"Longitude", rotas[i].Longitude.ToString().Replace(',', '.')},
                              {"Latitude", rotas[i].Latitude.ToString().Replace(',', '.')},
                              {"Ordem", rotas[i].Ordem.ToString()},
                              {"DataInsercao", rotas[i].DataInsercao.ToString()},
                              {"NomeRota", rotas[i].Rota.Nome.ToString()},
                              {"RotaMarca", rotas[i].IDRotaMarca.ToString()},
                          });
            }

            return d;
        }

        [WebMethod]
        [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
        public List<Hashtable> GetRotaId(int idRota)
        {
            List<Hashtable> d = new List<Hashtable>();

            RotaCoordenada rc = new RotaCoordenada();
            var r = rc.GetRotaById(idRota);

            for (int i = 0; i < r.Count; i++)
            {
                d.Add(new Hashtable
                          {
                              {"IDRotaCoordenada", r[i].IDRotaCoordenada.ToString()},
                              {"Longitude", r[i].Longitude.ToString().Replace(',', '.')},
                              {"Latitude", r[i].Latitude.ToString().Replace(',', '.')},
                          });
            }


            return d;
        }

        [WebMethod]
        [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
        public List<Hashtable> getPercursoVeiculo(int idCarro, int idRota)
        {
            List<Hashtable> d = new List<Hashtable>();
            DateTime from = new DateTime();
            DateTime to = new DateTime();

            RotaViatura rv = new RotaViatura();
            rv = rv.GetDatasByRotaAndViatura(idCarro, idRota);

            from = rv.DataIni;
            to = rv.DataFim;
            int idRotaViatura = rv.IdRotaViatura;

            RotaCoordenada rc = new RotaCoordenada();
            Gps g = new Gps();
            //  var r = g.getParagensEspec(idCarro,from,to);
            var perc = g.GetCoordinatesFromDay(idCarro, from, to);
            for (int i = 0; i < perc.Count; i++)
            {
                d.Add(new Hashtable
                          {
                              {"Longitude", perc[i].Longitude.ToString().Replace(',', '.')},
                              {"Latitude", perc[i].Latitude.ToString().Replace(',', '.')},
                          });
            }


            return d;
        }

        [WebMethod]
        [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
        public object insertEntregaMarca(int idMarcaActual, int idRotaViatura, string funcionario, int h, int m)
        {
            int insert = -1;
            RotaMarca rm = new RotaMarca();
            rm = rm.getMarcaById(idMarcaActual);
            //Buscar Latitude/Longitude da Marca -> Check
            RotaViatura rv = new RotaViatura();
            int IdRv = rv.getIdViaturaByIdRotaViatura(idRotaViatura);
            //rv.IdViatura = IdRv;
            ViaturaCollection v = new ViaturaCollection();
            Entrega ent = new Entrega();


            if (h != DateTime.Now.Hour)
            {
                DateTime dataActual = DateTime.Now;
                DateTime dataInserida = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, h, m, 0);

                IList<ViaturaCollection> l = v.getLatLongInTime(IdRv, dataActual, dataInserida);


//                //VERIFICAR LATITUDE E LONGITUDE DO VEICULO AQUELA HORA NA TABELA GEOCODES 
//                //verificar se coincide com a Latitude e Longitude DA MARCA com uma margem de erro RAZOAVEL
//                //geocodes latitude e longitude num espaço de tempo verificar se esta num raio de KM razoavel segundo a funcao que o domingos me vai dizer e entao vai fazer o insert! 

//                /*
//Haversine
//formula:	 a = sin²(Δφ/2) + cos(φ1).cos(φ2).sin²(Δλ/2)
//c = 2.atan2(√a, √(1−a))
//d = R.c
//where	φ is latitude, λ is longitude, R is earth’s radius (mean radius = 6,371km)
//    note that angles need to be in radians to pass to trig functions!*/

//                /*
//                 JavaScript:	
//var R = 6371; // km
//var dLat = (lat2-lat1).toRad();
//var dLon = (lon2-lon1).toRad();
//var lat1 = lat1.toRad();
//var lat2 = lat2.toRad();

//var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
//        Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2); 
//var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
//var d = R * c;
//                 */
                var R = 6371;
                var lat1 = Math.PI*rm.Latitude/180.0;
                var long1 = Math.PI*rm.Longitude/180.0;

                //
                double lat2=0;
                double long2=0;
                

                foreach (ViaturaCollection vc in l)
                {
                    lat2 = Math.PI*vc.lat/180.0;
                    long2 = Math.PI*vc.lng/180.0;
                    var dLat = (lat2 - lat1);
                    var dLon = (long2 - long1);

                    var a = Math.Sin(dLat/2)*Math.Sin(dLat/2) +
                            Math.Sin(dLon/2)*Math.Sin(dLon/2)*Math.Cos(lat1)*Math.Cos(lat2);
                    var c = 2*Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
                    var d = R*c;

                    if (d <= 50)
                    {
                        ent.Data = vc.d;
                        ent.DataInsercao = DateTime.Now;
                        ent.Funcionario = funcionario;
                        ent.Rm.IDRotaMarca = idMarcaActual;
                        ent.Rv.IdRotaViatura = idRotaViatura;
                        ent.Latitude = lat2;
                        ent.Longitude = long2;
                        insert = ent.InserirEntrega(ent);
                        break;
                    }
                    else
                    {
                        return
                            new {success = false, message = "Distância na hora inserida não coincide com localização"};
                    }
                }
            }
            else
            {
                ent.Data = new DateTime();
                ent.Data = DateTime.Now;
                ent.DataInsercao = DateTime.Now;
                ent.Funcionario = funcionario;
                ent.Rm.IDRotaMarca = idMarcaActual;
                ent.Rv.IdRotaViatura = idRotaViatura;
                ent.Latitude = rm.Latitude;
                ent.Longitude = rm.Longitude;
                insert = ent.InserirEntrega(ent);

                //IR A TABELA VIATURA VERIFICAR LONGITUDE E LATITUDE
                //verificar se coincide com a Latitude e Longitude DA MARCA
            }

            //IDRotaViatura 
            //Buscar Latitude/Longitude da Viatura;

            //IDMarca
            //Funcionario
            if (insert == 1)
            {
                return new {success = true, message = "Yes"};
            }
            else
            {
                return new {success = true, message = "ERRO"};
            }
        }
    }
}